/**
 * @class 特殊天体系统
 * @author DuskyHuang 圣子
 * @description 河内恒星、黑洞、双星多星系统等
*/

import { _decorator, Node } from 'cc';
import { Controller, core, utils } from 'cfw';
import { Star } from '../stellar/star';
import { Blackhole } from '../stellar/black-hole';
import { StellarGouldBelt } from './stellar-gould-belt';
import { CosmosProxy, visit } from 'proxies';
import { Res, SceneGraph } from 'const';
import { SolarSystem } from './solar-system';
const { findComp } = utils;
const { ccclass, property } = _decorator;

@ccclass('cocosmos.specific-system')
export class SpecificSystem extends Controller {

    @property(Node) public binaryStars: Node = null;
    @property(Blackhole) public blackhole: Blackhole = null;
    @property(Star) public centerStar: Star = null;
    protected onLoad(): void { this._init()._listen(); }

    protected start(): void {
        this._hideAll();
    }

    protected update(): void {

    }

    public loadStellarTargetAndSync(onlyTargetAndTemp: boolean = false): void {
        this._hideAll();
        const { name, into } = visit.transInfo;
        const viewer = utils.findCamera(COSMOS, MAIN);
        // console.debug("loadStellarTargetAndSync", onlyTargetAndTemp, visit.transInfo.transEnum, into);
        switch (into) {
            case "star": {
                this.binaryStars.active = !onlyTargetAndTemp;
                if (name === 'Sun') {
                    visit.transInfo.target = this._solar.sun;
                } else {
                    const config = core.res.getConfigItem<starConfig>(VISITABLE_STARS, name);
                    if (!config) return console.error('[specific.loadSystem]', 'cant find star config:', name);
                    const { ab, cst } = config;
                    const star = this._stellar.getStar(cst, ab);
                    if (!star) return console.error('[specific.loadSystem]', 'cant find star obj:', name);
                    visit.transInfo.target = this.centerStar;
                    if (onlyTargetAndTemp) {
                        // 不能loadReference(star) => relative-scalar false in pre-half
                        // 不能什么都不做 => target.refer(refers.to) not set
                        visit.transInfo.stellar.refers.temp = star.node;
                        return;
                    } else {
                        this.centerStar.loadReference(star);
                        this.centerStar.node.name = name;
                        this.centerStar.loadConfig(config, viewer, BASE_POW10);
                    }
                }
            } break;
            case "blackhole": {
                this.blackhole.node.active = !onlyTargetAndTemp;
                if (name === 'Sun') {
                    visit.transInfo.target = this._solar.sun;
                } else {
                    const config = core.res.getConfigItem<blackHoleConfig>(VISITABLE_BLACK_HOLES, name);
                    if (!config) return console.error('[specific.loadSystem]', 'cant find blackhole config:', name);
                    const { ab, cst } = config;
                    const blackhole = this._stellar.getStar(cst, ab);
                    if (!blackhole) return console.error('[specific.loadSystem]', 'cant find blackhole obj:', name);
                    visit.transInfo.target = this.blackhole;
                    if (onlyTargetAndTemp) {
                        // 不能loadReference(star) => relative-scalar false in pre-half
                        // 不能什么都不做 => target.refer(refers.to) not set
                        visit.transInfo.stellar.refers.temp = blackhole.node;
                        return;
                    } else {
                        this.blackhole.loadReference(blackhole);
                        this.blackhole.node.name = name;
                        this.blackhole.loadConfig(config, viewer, BASE_POW10);
                    }
                }
            } break;
            default: console.warn('[specific.loadSystem]', 'undefined into:', into);
        }
    }

    protected lateUpdate(): void {
        // de
    }

    private _init(): this {
        this._stellar = findComp(StellarGouldBelt, this.node.parent, STELLAR);
        this._solar = findComp(SolarSystem, this.node.parent, SOLAR);
        return this;
    }

    private _listen(): void { }

    public freeSystem(): void {
        this._hideAll();
    }

    private _hideAll(): void { this.node.children.forEach(child => child.active = false); }

    private _stellar: StellarGouldBelt;
    private _solar: SolarSystem;
}

const { STELLAR, SOLAR, COSMOS, Cameras: { MAIN } } = SceneGraph;
const BASE_POW10 = CosmosProxy.Scopes.Specific[2];
const { VISITABLE_STARS, VISITABLE_BLACK_HOLES } = Res.Configs;